Index: gcc/rtl-factoring.c
===================================================================
--- gcc/rtl-factoring.c	(revision 132522)
+++ gcc/rtl-factoring.c	(working copy)
@@ -551,8 +551,8 @@
   df_simulate_artificial_refs_at_end (bb, &live);
 
   /* Propagate until INSN if found.  */
-  for (x = BB_END (bb); x != insn;)
-    df_simulate_one_insn_backwards (bb, insn, &live);
+  for (x = BB_END (bb); x != insn; x = PREV_INSN(x))
+    df_simulate_one_insn_backwards (bb, x, &live);
 
   /* Clear registers live after INSN.  */
   renumbered_reg_set_to_hard_reg_set (&hlive, &live);
@@ -562,7 +562,7 @@
   for (i = 0; i < length;)
     {
       rtx prev = PREV_INSN (x);
-      df_simulate_one_insn_backwards (bb, insn, &live);
+      df_simulate_one_insn_backwards (bb, x, &live);
 
       if (INSN_P (x))
         {
@@ -949,6 +949,17 @@
   return sym;
 }
 
+/* Splits basic block at the requested insn and rebuilds dataflow.  */
+
+static basic_block
+asplit_block(basic_block bb, rtx insn)
+{
+  basic_block next;
+  next = split_block (bb, insn)->dest;
+  df_analyze ();
+  return next;
+}
+
 /* Ensures that INSN is the last insn in its block and returns the block label
    of the next block.  */
 
@@ -959,7 +970,7 @@
   if ((insn == BB_END (bb)) && (bb->next_bb != EXIT_BLOCK_PTR))
     return block_label (bb->next_bb);
   else
-    return block_label (split_block (bb, insn)->dest);
+    return block_label (asplit_block (bb, insn));
 }
 
 /* Ensures that the last insns of the best pattern and its matching sequences
@@ -1008,8 +1019,9 @@
 
   /* Emit an indirect jump via the link register after the sequence acting
      as the return insn.  Also emit a barrier and update the basic block.  */
-  retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
-                                 BB_END (bb));
+  if (!find_reg_note (BB_END(bb), REG_NORETURN, NULL))
+    retjmp = emit_jump_insn_after (gen_indirect_jump (pattern_seqs->link_reg),
+                                   BB_END (bb));
   emit_barrier_after (BB_END (bb));
 
   /* Replace all outgoing edges with a new one to the block of RETLABEL.  */
@@ -1025,7 +1037,7 @@
       for (; i < sb->length; i++)
         insn = prev_insn_in_block (insn);
 
-      sb->label = block_label (split_block (bb, insn)->dest);
+      sb->label = block_label (asplit_block (bb, insn));
     }
 
   /* Emit an insn saving the return address to the link register before the
@@ -1067,7 +1079,7 @@
           /* Delete the insns of the sequence.  */
           for (i = 0; i < sb->length; i++)
             insn = prev_insn_in_block (insn);
-          delete_basic_block (split_block (bb, insn)->dest);
+          delete_basic_block (asplit_block (bb, insn));
 
           /* Emit an insn saving the return address to the link register
              before the deleted sequence.  */
